package com.leo.utils;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.graphics.Point;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.telephony.TelephonyManager;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;

import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.regex.Pattern;


/**
 *
 * created by leo 2016/04/25
 */
public final class AndroidUtils {

    public static final boolean DEBUG = false;

    public static final String PREFIX_IMAGE = "IMG_";
    public static final String EXTENSION_JPEG = ".jpg";
    public static final String EXTENSION_PNG = ".png";
    public static final String FILENAME_NOMEDIA = ".nomedia";

    public static final DateFormat IMG_FILE_NAME_FORMAT = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US);

    public static final int HEAP_SIZE_LARGE = 48 * 1024 * 1024;
    public static final String ENCODING_UTF8 = "UTF-8";
    private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+");

    private AndroidUtils() {
    }

    /**
     * 清除cookies
     * (用户退出时，要清除WebView的Cookie)
     *
     * @param context
     */
    public static void clearCookies(Context context) {
        @SuppressWarnings("unused")
        CookieSyncManager cookieSyncMngr =
                CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.removeAllCookie();
    }

    /**
     *  判断有无SD卡
     * @return
     */
    public static boolean hasSdcard() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    /**
     * 获取一个唯一Id
     *
     * @return String
     */
    public static final String getUniqueID() {
        int t1 = (int) (System.currentTimeMillis() / 1000L);
        int t2 = (int) System.nanoTime();
        int t3 = (new Random()).nextInt();
        int t4 = (new Random()).nextInt();
        byte[] b1 = getBytes(t1);
        byte[] b2 = getBytes(t2);
        byte[] b3 = getBytes(t3);
        byte[] b4 = getBytes(t4);
        byte[] bUniqueID = new byte[16];
        System.arraycopy(b1, 0, bUniqueID, 0, 4);
        System.arraycopy(b2, 0, bUniqueID, 4, 4);
        System.arraycopy(b3, 0, bUniqueID, 8, 4);
        System.arraycopy(b4, 0, bUniqueID, 12, 4);
        return Base64.encodeToString(bUniqueID, 2);
    }

    /**
     * 获取设备的IMEI(国际移动装备辨识码)
     *
     * @param context
     * @return String
     */
    public static String getImei(Context context) {
        String imei = null;
        if (context != null) {
            try {
                TelephonyManager e = (TelephonyManager) context
                        .getSystemService(Context.TELEPHONY_SERVICE);
                if (e != null) {
                    imei = e.getDeviceId();
                }
            } catch (Exception var3) {
            }
        }

        if (StringUtils.isEmpty(imei)) {
            imei = "";
        }

        return imei;
    }

    /**
     *  IMSI for a GSM phone
     */
    public static String getImsi(Context context) {
        String ret = null;
        if(context != null) {
            try {
                TelephonyManager tm;
                if((tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE)) != null) {
                    ret = tm.getSubscriberId();
                }
            } catch (Exception e) {
            }
        }

        if(StringUtils.isEmpty(ret)) {
            ret = "";
        }

        return ret;
    }

    /**
     *   通过包名卸载应用
     *
     * @param context
     * @param packageName
     * @return
     */
    public static boolean checkAppExist(Context context, String packageName) {
        if (context == null || packageName == null || "".equals(packageName))
            return false;
        try {
            ApplicationInfo info = context.getPackageManager()
                    .getApplicationInfo(packageName,
                            PackageManager.GET_UNINSTALLED_PACKAGES);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    /**
     * 加载app
     * @param mContext
     * @param packageName
     */
    public static void launchApp(Context mContext, String packageName) {
        Intent launchIntent = mContext.getPackageManager().getLaunchIntentForPackage(packageName);
        mContext.startActivity(launchIntent);
    }

    /**
     * 判断android设备是否root过。
     *
     * @return boolean
     */
    private final static int kSystemRootStateUnknow = -1;
    private final static int kSystemRootStateDisable = 0;
    private final static int kSystemRootStateEnable = 1;
    private static int systemRootState = kSystemRootStateUnknow;

    public static boolean isAndroidRoot() {

        if (systemRootState == kSystemRootStateEnable) {
            return true;
        } else if (systemRootState == kSystemRootStateDisable) {
            return false;
        }

        File f = null;
        final String kSuSearchPaths[] = {"/system/bin/", "/system/xbin/", "/system/sbin/", "/sbin/", "/vendor/bin/"};
        try {
            for (int i = 0; i < kSuSearchPaths.length; i++) {
                f = new File(kSuSearchPaths[i] + "su");
                if (f != null && f.exists()) {
                    systemRootState = kSystemRootStateEnable;
                    return true;
                }
            }
        } catch (Exception e) {

        }

        try {
            //root过的android手机都会有superuser这个apk
            File file = new File("/system/app/Superuser.apk");
            if (file.exists()) {
                systemRootState = kSystemRootStateEnable;
                return true;
            }
        } catch (Exception e) {

        }

        systemRootState = kSystemRootStateDisable;
        return false;
    }

    /**
     * 得到android设备的mac地址。
     * 注意：使用getLocalMacAddress必须要保证sdk 的 manifest 文件中包含 android.permission.ACCESS_WIFI_STATE 权限，并且 api 级别大于9。
     *
     * @return boolean
     */
    public static String getLocalMacAddress(Context context) {
        WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        try {
            WifiInfo info = wifi.getConnectionInfo();
            return info.getMacAddress();
        } catch (Throwable e) {
        }
        return "";
    }

    /**
     * 获取软件版本 name
     *
     * @param context
     * @return
     */
    public static String getAppVersionName(Context context) {
        if (context == null) {
            return "";
        }
        try {
            PackageInfo pkg = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            return pkg.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            return "";
        }
    }

    /**
     *  获取AppVersion code
     * @param context
     * @return
     */
    public static int getAppVersionCode(Context context) {
        if(context == null) {
            return 0;
        } else {
            try {
                PackageInfo e = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
                return e.versionCode;
            } catch (PackageManager.NameNotFoundException var2) {
                return 0;
            }
        }
    }



    /**
     * 获取友盟渠道号
     */
    public static String getUmengChannel(Context context) {
        return getAppMetaData(context, "UMENG_CHANNEL", "eclicks_default");
    }

    /**
     * 获取百度Api Key
     */
    public static String getBaiduApiKey(Context context) {
        return getAppMetaData(context, "com.baidu.lbsapi.API_KEY", "pEfSTCdRdbkIlHCTsjteNGw0");
    }

    /**
     * 获取Manifests MetaData
     *
     * @param context
     * @param key
     * @param defVal
     * @return
     */
    public static String getAppMetaData(Context context, String key, String defVal) {
        if (context == null) {
            return defVal;
        }
        try {
            ApplicationInfo appi = context.getPackageManager()
                    .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
            Bundle bundle = appi.metaData;
            return (String) bundle.get(key);
        } catch (Exception e) {
            return defVal;
        }
    }


    /**
     * 获取屏幕分辨率字符串
     *
     * @param context
     * @return
     */
    public static String getDeviceResolution(Context context) {
        Pair<Integer, Integer> deviceHWPixels = getDeviceWHPixels(context);
        return deviceHWPixels.second + "x" + deviceHWPixels.first;
    }

    /**
     * 获取屏幕分辨率
     *
     * @param context
     * @return Pair<width, height>
     */
    @SuppressLint("NewApi")
    public static Pair<Integer, Integer> getDeviceWHPixels(Context context) {
        try {
            WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            if (hasHoneycombMR2()) {
                Point size = new Point();
                display.getSize(size);
                return new Pair<>(size.x, size.y);
            } else {
                DisplayMetrics dm = context.getResources().getDisplayMetrics();
                return new Pair<>(dm.widthPixels, dm.heightPixels);
            }
        } catch (Exception e) {
        }
        return new Pair<>(-1, -1);
    }


    public static boolean isLargeHeap() {
        return Runtime.getRuntime().maxMemory() > HEAP_SIZE_LARGE;
    }

    public static boolean noSdcard() {
        return !Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
    }

    /**
     * Execute an {@link AsyncTask} on a thread pool.
     *
     * @param task Task to add.
     * @param args Optional arguments to pass to {@link AsyncTask#execute(Object[])}.
     * @param <T>  Task argument type.
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static <T> void execute(AsyncTask<T, ?, ?> task, T... args) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            task.execute(args);
        } else {
            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, args);
        }
    }

    public static boolean hasCamera(Context context) {
        PackageManager pm = context.getPackageManager();
        return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)
                || pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
    }

    /**
     * 保存了新的图片，触发系统Media 扫描
     */
    public static void mediaScan(Context context, Uri uri) {
        if (context == null) return;
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(uri);
        context.sendBroadcast(intent);
    }

    // another media scan way
    public static void addToMediaStore(Context context, File file) {
        String[] path = new String[]{file.getPath()};
        MediaScannerConnection.scanFile(context, path, null, null);
    }

    /**
     * 判断版本是否支持 DrawTextOnPath 方法
     * 否则需要使用 setLayerType(View.LAYER_TYPE_SOFTWARE, null);
     *
     * @return
     */
    public static boolean isSupportDrawTextOnPath() {
        return !(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN
                && Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1);
    }

    /**
     * 硬件加速有bug
     * https://code.google.com/p/android/issues/detail?id=29944
     *
     * @param v
     */
    public static void disableHardwareRendering(View v) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            v.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
    }

    public static boolean hasGingerbread() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD;
    }

    public static boolean hasHoneycomb() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
    }

    public static boolean isPreHoneycomb() {
        return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
    }

    public static boolean hasHoneycombMR1() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1;
    }

    public static boolean hasHoneycombMR2() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2;
    }

    public static boolean hasIceCreamSandwich() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
    }

    public static boolean isPreIceCreamSandwich() {
        return Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH;
    }

    public static boolean hasJellyBean() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
    }

    public static boolean hasKitkat() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    }

    @TargetApi(11)
    public static void setStrictMode(boolean enable) {
        if (!enable) {
            return;
        }
        if (hasGingerbread()) {
            StrictMode.ThreadPolicy.Builder threadPolicyBuilder =
                    new StrictMode.ThreadPolicy.Builder()
                            .detectAll()
                            .penaltyLog();
            StrictMode.VmPolicy.Builder vmPolicyBuilder =
                    new StrictMode.VmPolicy.Builder()
                            .detectAll()
                            .penaltyLog();
            StrictMode.setThreadPolicy(threadPolicyBuilder.build());
            StrictMode.setVmPolicy(vmPolicyBuilder.build());
        }
    }

    /**
     * 重启一个Activity
     *
     * @param activity Activity
     */
    public static void restartActivity(final Activity activity) {
        Intent intent = activity.getIntent();
        activity.overridePendingTransition(0, 0);
        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        activity.finish();
        activity.overridePendingTransition(0, 0);
        activity.startActivity(intent);
    }


    public static void enableComponent(Context context, Class<?> clazz) {
        setComponent(context, clazz, true);
    }

    public static void disableComponent(Context context, Class<?> clazz) {
        setComponent(context, clazz, false);
    }

    public static void setComponent(Context context, Class<?> clazz, boolean enable) {
        ComponentName receiver = new ComponentName(context, clazz);
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(receiver,
                enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
                        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP
        );
    }

    public static Intent getBatteryStatus(Context context) {
        Context appContext = context.getApplicationContext();
        return appContext.registerReceiver(null,
                new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    }


    private static Signature getSignature(Context context) {
        final PackageManager pm = context.getPackageManager();
        PackageInfo info = null;
        try {
            info = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
        } catch (Exception ignored) {
        }

        Signature signature = null;
        if (info != null) {
            Signature[] signatures = info.signatures;
            if (signatures != null && signatures.length > 0) {
                signature = signatures[0];
            }
        }

        if (DEBUG) {
            L.v("getSignature() " + signature);
        }


        return signature;
    }

    private static byte[] getBytes(int i) {
        byte[] bInt = new byte[4];
        bInt[3] = (byte) (i % 256);
        int value = i >> 8;
        bInt[2] = (byte) (value % 256);
        value >>= 8;
        bInt[1] = (byte) (value % 256);
        value >>= 8;
        bInt[0] = (byte) (value % 256);
        return bInt;
    }

    /**
     * 获取屏幕宽度
     *
     * @param context
     * @return
     */
    public static int getDisplayWidth(Context context) {
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        return dm.widthPixels;
    }

    /**
     * 获取屏幕高度
     *
     * @param context
     * @return
     */
    public static int getDisplayHeight(Context context) {
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        return dm.heightPixels;
    }

    /**
     * 获取版本号(内部识别号)
     *
     * @param context
     * @return
     */
    public static int getVersionCode(Context context) {
        try {
            PackageInfo pi = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            return pi.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     *  检测用户是否正常使用App
     * @param context
     * @return
     */
    @SuppressWarnings("deprecation")
    public static boolean checkAppRuning(Context context) {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> list = manager.getRunningTasks(1);// 获取正在运行的任务。
        // 获取task堆栈顶端的activity的包名，以次判断应用否正在运行
        if (list.get(0).topActivity.getPackageName().equals(context.getPackageName())) {
            return true;
        }
        return false;
    }

}